package com.bcoin.rankagent;


import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;


public class RankAgentServer {

    private static final String DEFAULT_URL = "/";


    public void run(int port, String url) throws Exception {

        EventLoopGroup bossGrp = new NioEventLoopGroup();
        EventLoopGroup workerGrp = new NioEventLoopGroup();
        try {
            ServerBootstrap sb = new ServerBootstrap();

            sb.group(bossGrp, workerGrp)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                                      protected void initChannel(SocketChannel socketChannel) throws Exception {
                                          // 请求消息解码器
                                          socketChannel.pipeline().addLast("http-decoder", new HttpRequestDecoder());
                                          // 目的是将多个消息转换为单一的request或者response对象
                                          socketChannel.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536));
                                          //响应解码器
                                          socketChannel.pipeline().addLast("http-encoder", new HttpResponseEncoder());
                                          //目的是支持异步大文件传输
                                          socketChannel.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
                                          // 业务逻辑
                                          socketChannel.pipeline().addLast("fileServerHandler", new RankAgentServerHandler(url));
                                      }
                                  }
                    );

            ChannelFuture future = sb.bind("0.0.0.0", port).sync();
            System.out.println("Server started at " + port);
            future.channel().closeFuture().sync();

        } catch (Exception e) {
            e.fillInStackTrace();
        } finally {
            bossGrp.shutdownGracefully();
            workerGrp.shutdownGracefully();
        }
    }


    public static void main(String[] args) throws Exception {

        int port = 8080;

        if (args.length > 0) {
            try {
                port = Integer.parseInt(args[0]);
            } catch (NumberFormatException e) {
                e.fillInStackTrace();
            }
        }
        String url = DEFAULT_URL;
        if (args.length > 1) {
            url = args[1];
        }

        new RankAgentServer().run(port, url);
    }
}
